﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using StyleMVVM.DependencyInjection;
#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;

#else
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

#endif

namespace StyleMVVM.Conventions.Service
{
	public sealed class ConventionsService : IConventionsService
	{
		private string viewModelSuffix = "ViewModel";

		public static void RegisterExport(IDependencyInjectionContainer container)
		{
			container.Register(typeof(ConventionsService)).As(typeof(IConventionsService)).AndShared();
		}

		public string ViewModelSuffix
		{
			get { return viewModelSuffix; }
			set { viewModelSuffix = value; }
		}

		public IEnumerable<string> ViewModelNameConventions(Type viewType)
		{
			string viewName = viewType.Name;
			string viewNameLower = viewType.Name.ToLower();
			List<string> returnValue = new List<string>();

			if (viewNameLower.EndsWith("view"))
			{
				returnValue.Add(viewName.Substring(0, viewName.Length - 4) + ViewModelSuffix);
				returnValue.Add(viewName + ViewModelSuffix);
			}
			else if (viewNameLower.EndsWith("page"))
			{
				returnValue.Add(viewName.Substring(0, viewName.Length - 4) + ViewModelSuffix);
				returnValue.Add(viewName + ViewModelSuffix);
			}
			else
			{
				returnValue.Add(viewName + ViewModelSuffix);
			}

			return returnValue;
		}

        public DependencyProperty GetPropertyConvention(Type controlType, object propertyInfoType)
        {
            PropertyInfo propertyInfo = (PropertyInfo)propertyInfoType;
            TypeInfo controlTypeInfo = controlType.GetTypeInfo();

            if (typeof(TextBox).GetTypeInfo().IsAssignableFrom(controlTypeInfo))
            {
                return TextBox.TextProperty;
            }

            if (typeof(TextBlock).GetTypeInfo().IsAssignableFrom(controlTypeInfo))
            {
                return TextBlock.TextProperty;
            }

#if !DOT_NET
            if (typeof(PasswordBox).GetTypeInfo().IsAssignableFrom(controlTypeInfo))
            {
                return PasswordBox.PasswordProperty;
            }
#endif
            if (typeof(Image).GetTypeInfo().IsAssignableFrom(controlTypeInfo))
            {
                return Image.SourceProperty;
            }

#if NETFX_CORE
            if (typeof(ToggleSwitch).GetTypeInfo().IsAssignableFrom(controlTypeInfo) &&
                (propertyInfo.PropertyType == typeof(bool) || propertyInfo.PropertyType == typeof(bool?)))
            {
                return ToggleSwitch.IsOnProperty;
            }
#endif

            if (typeof(ToggleButton).GetTypeInfo().IsAssignableFrom(controlTypeInfo) &&
                (propertyInfo.PropertyType == typeof(bool) || propertyInfo.PropertyType == typeof(bool?)))
            {
                return ToggleButton.IsCheckedProperty;
            }

            if (typeof(ButtonBase).GetTypeInfo().IsAssignableFrom(controlTypeInfo) &&
                typeof(ICommand).GetTypeInfo().IsAssignableFrom(propertyInfo.PropertyType.GetTypeInfo()))
            {
                return ButtonBase.CommandProperty;
            }

            if (typeof(ContentControl).GetTypeInfo().IsAssignableFrom(controlType.GetTypeInfo()))
            {
                return ContentControl.ContentProperty;
            }

            if (typeof(ItemsControl).GetTypeInfo().IsAssignableFrom(controlTypeInfo) &&
                propertyInfo.PropertyType != typeof(string) &&
                typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(propertyInfo.PropertyType.GetTypeInfo()))
            {
                return ItemsControl.ItemsSourceProperty;
            }

            if (typeof(Selector).GetTypeInfo().IsAssignableFrom(controlTypeInfo))
            {
                return Selector.SelectedItemProperty;
            }

            return null;
        }
	}
}